package com.fsnbigdata.service.impl;

import com.fsnbigdata.domain.*;
import com.fsnbigdata.domain.dto.NamingPair3;
import com.fsnbigdata.repository.DistributionRepository;
import com.fsnbigdata.repository.OrganismImageRepository;
import com.fsnbigdata.repository.OrganismRepository;
import com.fsnbigdata.repository.TaxonomyRepository;
import com.fsnbigdata.service.api.ConservationStatusService;
import com.fsnbigdata.service.api.DistributionService;
import com.fsnbigdata.service.api.DocumentService;
import com.fsnbigdata.service.api.GermplasmService;
import com.fsnbigdata.service.api.OrganismDocumentService;
import com.fsnbigdata.service.api.OrganismImageService;
import com.fsnbigdata.service.api.OrganismService;
import com.fsnbigdata.service.api.OrganismSpecimenService;
import com.fsnbigdata.service.api.OrganismVideoService;
import com.fsnbigdata.service.api.TaxonomyService;
import com.fsnbigdata.util.ObjectNull;
import com.fsnbigdata.vo.NewClass;
import com.fsnbigdata.vo.Tree;
import com.querydsl.core.types.Predicate;
import io.springlets.data.domain.GlobalSearch;

import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.roo.addon.layers.service.annotations.RooServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Root;

/**
 * = OrganismServiceImpl
 *
 * TODO Auto-generated class documentation
 *
 */
@RooServiceImpl(service = OrganismService.class)
@Service
@Transactional(readOnly = true)
public class OrganismServiceImpl implements OrganismService {

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private ConservationStatusService conservationStatusService;

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private OrganismRepository organismRepository;

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private TaxonomyRepository taxonomyRepository;

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private DistributionRepository distributionRepository;

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private OrganismImageRepository organismImageRepository;

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private OrganismImageService organismImageService;

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private TaxonomyService taxonomyService;

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private OrganismVideoService organismVideoService;

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private DocumentService documentService;

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private DistributionService distributionService;

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private OrganismSpecimenService organismSpecimenService;

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private OrganismDocumentService organismDocumentService;

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private GermplasmService germplasmService;

    class O{
        private Long id;
        private String name;
        private String name_en;

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getName_en() {
            return name_en;
        }

        public void setName_en(String name_en) {
            this.name_en = name_en;
        }
    }

    /**
     * TODO Auto-generated constructor documentation
     *
     * @param organismRepository
     * @param conservationStatusService
     * @param distributionService
     * @param documentService
     * @param germplasmService
     * @param organismDocumentService
     * @param organismImageService
     * @param organismSpecimenService
     * @param organismVideoService
     * @param taxonomyService
     */
    @Autowired
    public OrganismServiceImpl(ConservationStatusService conservationStatusService, OrganismRepository organismRepository, TaxonomyRepository taxonomyRepository, DistributionRepository distributionRepository, OrganismImageRepository organismImageRepository, OrganismImageService organismImageService, TaxonomyService taxonomyService, OrganismVideoService organismVideoService, DocumentService documentService, DistributionService distributionService, OrganismSpecimenService organismSpecimenService, OrganismDocumentService organismDocumentService, GermplasmService germplasmService) {
        this.conservationStatusService = conservationStatusService;
        this.organismRepository = organismRepository;
        this.taxonomyRepository = taxonomyRepository;
        this.distributionRepository = distributionRepository;
        this.organismImageRepository = organismImageRepository;
        this.organismImageService = organismImageService;
        this.taxonomyService = taxonomyService;
        this.organismVideoService = organismVideoService;
        this.documentService = documentService;
        this.distributionService = distributionService;
        this.organismSpecimenService = organismSpecimenService;
        this.organismDocumentService = organismDocumentService;
        this.germplasmService = germplasmService;
    }


    public OrganismImageRepository getOrganismImageRepository() {
        return organismImageRepository;
    }

    public void setOrganismImageRepository(OrganismImageRepository organismImageRepository) {
        this.organismImageRepository = organismImageRepository;
    }

    public DistributionRepository getDistributionRepository() {
        return distributionRepository;
    }

    public void setDistributionRepository(DistributionRepository distributionRepository) {
        this.distributionRepository = distributionRepository;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return OrganismRepository
     */
    public OrganismRepository getOrganismRepository() {
        return organismRepository;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organismRepository
     */
    public void setOrganismRepository(OrganismRepository organismRepository) {
        this.organismRepository = organismRepository;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return ConservationStatusService
     */
    public ConservationStatusService getConservationStatusService() {
        return conservationStatusService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param conservationStatusService
     */
    public void setConservationStatusService(ConservationStatusService conservationStatusService) {
        this.conservationStatusService = conservationStatusService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return DistributionService
     */
    public DistributionService getDistributionService() {
        return distributionService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param distributionService
     */
    public void setDistributionService(DistributionService distributionService) {
        this.distributionService = distributionService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return DocumentService
     */
    public DocumentService getDocumentService() {
        return documentService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param documentService
     */
    public void setDocumentService(DocumentService documentService) {
        this.documentService = documentService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return GermplasmService
     */
    public GermplasmService getGermplasmService() {
        return germplasmService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param germplasmService
     */
    public void setGermplasmService(GermplasmService germplasmService) {
        this.germplasmService = germplasmService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return OrganismDocumentService
     */
    public OrganismDocumentService getOrganismDocumentService() {
        return organismDocumentService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organismDocumentService
     */
    public void setOrganismDocumentService(OrganismDocumentService organismDocumentService) {
        this.organismDocumentService = organismDocumentService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return OrganismImageService
     */
    public OrganismImageService getOrganismImageService() {
        return organismImageService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organismImageService
     */
    public void setOrganismImageService(OrganismImageService organismImageService) {
        this.organismImageService = organismImageService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return OrganismSpecimenService
     */
    public OrganismSpecimenService getOrganismSpecimenService() {
        return organismSpecimenService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organismSpecimenService
     */
    public void setOrganismSpecimenService(OrganismSpecimenService organismSpecimenService) {
        this.organismSpecimenService = organismSpecimenService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return OrganismVideoService
     */
    public OrganismVideoService getOrganismVideoService() {
        return organismVideoService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organismVideoService
     */
    public void setOrganismVideoService(OrganismVideoService organismVideoService) {
        this.organismVideoService = organismVideoService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return TaxonomyService
     */
    public TaxonomyService getTaxonomyService() {
        return taxonomyService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param taxonomyService
     */
    public void setTaxonomyService(TaxonomyService taxonomyService) {
        this.taxonomyService = taxonomyService;
    }

    public TaxonomyRepository getTaxonomyRepository() {
        return taxonomyRepository;
    }

    public void setTaxonomyRepository(TaxonomyRepository taxonomyRepository) {
        this.taxonomyRepository = taxonomyRepository;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organism
     * @param conservationStatusToAdd
     * @return Organism
     */
    @Override
    @Transactional
    public Organism addToConservationStatus(Organism organism, Iterable<ConservationStatus> conservationStatusToAdd) {
        organism.addToConservationStatus(conservationStatusToAdd);
        return getOrganismRepository().save(organism);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organism
     * @param distributionToAdd
     * @return Organism
     */
    @Override
    @Transactional
    public Organism addToDistribution(Organism organism, Iterable<Distribution> distributionToAdd) {
        organism.addToDistribution(distributionToAdd);
        return getOrganismRepository().save(organism);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organism
     * @param docsToAdd
     * @return Organism
     */
    @Override
    @Transactional
    public Organism addToDocs(Organism organism, Iterable<Long> docsToAdd) {
        List<Document> docs = getDocumentService().findAll(docsToAdd);
        organism.addToDocs(docs);
        return getOrganismRepository().save(organism);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organism
     * @param documentsToAdd
     * @return Organism
     */
    @Override
    @Transactional
    public Organism addToDocuments(Organism organism, Iterable<OrganismDocument> documentsToAdd) {
        organism.addToDocuments(documentsToAdd);
        return getOrganismRepository().save(organism);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organism
     * @param germplasmToAdd
     * @return Organism
     */
    @Override
    @Transactional
    public Organism addToGermplasm(Organism organism, Iterable<Germplasm> germplasmToAdd) {
        organism.addToGermplasm(germplasmToAdd);
        return getOrganismRepository().save(organism);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organism
     * @param imagesToAdd
     * @return Organism
     */
    @Override
    @Transactional
    public Organism addToImages(Organism organism, Iterable<OrganismImage> imagesToAdd) {
        organism.addToImages(imagesToAdd);
        return getOrganismRepository().save(organism);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organism
     * @param specimensToAdd
     * @return Organism
     */
    @Override
    @Transactional
    public Organism addToSpecimens(Organism organism, Iterable<OrganismSpecimen> specimensToAdd) {
        organism.addToSpecimens(specimensToAdd);
        return getOrganismRepository().save(organism);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organism
     * @param taxonomyToAdd
     * @return Organism
     */
    @Override
    @Transactional
    public Organism addToTaxonomy(Organism organism, Iterable<Taxonomy> taxonomyToAdd) {
        organism.addToTaxonomy(taxonomyToAdd);
        return getOrganismRepository().save(organism);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organism
     * @param videosToAdd
     * @return Organism
     */
    @Override
    @Transactional
    public Organism addToVideos(Organism organism, Iterable<OrganismVideo> videosToAdd) {
        organism.addToVideos(videosToAdd);
        return getOrganismRepository().save(organism);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organism
     * @param conservationStatusToRemove
     * @return Organism
     */
    @Override
    @Transactional
    public Organism removeFromConservationStatus(Organism organism, Iterable<Long> conservationStatusToRemove) {
        List<ConservationStatus> conservationStatus = getConservationStatusService().findAll(conservationStatusToRemove);
        organism.removeFromConservationStatus(conservationStatus);
        return getOrganismRepository().save(organism);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organism
     * @param distributionToRemove
     * @return Organism
     */
    @Override
    @Transactional
    public Organism removeFromDistribution(Organism organism, Iterable<Long> distributionToRemove) {
        List<Distribution> distribution = getDistributionService().findAll(distributionToRemove);
        organism.removeFromDistribution(distribution);
        return getOrganismRepository().save(organism);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organism
     * @param docsToRemove
     * @return Organism
     */
    @Override
    @Transactional
    public Organism removeFromDocs(Organism organism, Iterable<Long> docsToRemove) {
        List<Document> docs = getDocumentService().findAll(docsToRemove);
        organism.removeFromDocs(docs);
        return getOrganismRepository().save(organism);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organism
     * @param documentsToRemove
     * @return Organism
     */
    @Override
    @Transactional
    public Organism removeFromDocuments(Organism organism, Iterable<Long> documentsToRemove) {
        List<OrganismDocument> documents = getOrganismDocumentService().findAll(documentsToRemove);
        organism.removeFromDocuments(documents);
        return getOrganismRepository().save(organism);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organism
     * @param germplasmToRemove
     * @return Organism
     */
    @Override
    @Transactional
    public Organism removeFromGermplasm(Organism organism, Iterable<Long> germplasmToRemove) {
        List<Germplasm> germplasm = getGermplasmService().findAll(germplasmToRemove);
        organism.removeFromGermplasm(germplasm);
        return getOrganismRepository().save(organism);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organism
     * @param imagesToRemove
     * @return Organism
     */
    @Override
    @Transactional
    public Organism removeFromImages(Organism organism, Iterable<Long> imagesToRemove) {
        List<OrganismImage> images = getOrganismImageService().findAll(imagesToRemove);
        organism.removeFromImages(images);
        return getOrganismRepository().save(organism);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organism
     * @param specimensToRemove
     * @return Organism
     */
    @Override
    @Transactional
    public Organism removeFromSpecimens(Organism organism, Iterable<Long> specimensToRemove) {
        List<OrganismSpecimen> specimens = getOrganismSpecimenService().findAll(specimensToRemove);
        organism.removeFromSpecimens(specimens);
        return getOrganismRepository().save(organism);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organism
     * @param taxonomyToRemove
     * @return Organism
     */
    @Override
    @Transactional
    public Organism removeFromTaxonomy(Organism organism, Iterable<Long> taxonomyToRemove) {
        List<Taxonomy> taxonomy = getTaxonomyService().findAll(taxonomyToRemove);
        organism.removeFromTaxonomy(taxonomy);
        return getOrganismRepository().save(organism);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organism
     * @param videosToRemove
     * @return Organism
     */
    @Override
    @Transactional
    public Organism removeFromVideos(Organism organism, Iterable<Long> videosToRemove) {
        List<OrganismVideo> videos = getOrganismVideoService().findAll(videosToRemove);
        organism.removeFromVideos(videos);
        return getOrganismRepository().save(organism);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organism
     * @param docs
     * @return Organism
     */
    @Override
    @Transactional
    public Organism setDocs(Organism organism, Iterable<Long> docs) {
        List<Document> items = getDocumentService().findAll(docs);
        items.forEach(item -> {
            item.getOrganisms().size();
            item.getSpecimens().size();
        });
        Set<Document> currents = organism.getDocs();
        Set<Document> toRemove = new HashSet<Document>();
        for (Iterator<Document> iterator = currents.iterator(); iterator.hasNext(); ) {
            Document nextDocument = iterator.next();
            if (items.contains(nextDocument)) {
                items.remove(nextDocument);
            } else {
                toRemove.add(nextDocument);
            }
        }
        organism.removeFromDocs(toRemove);
        organism.addToDocs(items);
        // Force the version update of the parent side to know that the parent has changed
        // because it has new books assigned
        //TODO organism.setVersion(organism.getVersion() + 1);
        return getOrganismRepository().save(organism);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param organism
     */
    @Override
    @Transactional
    public void delete(Organism organism) {
        // Clear bidirectional one-to-many parent relationship with ConservationStatus
        for (ConservationStatus item : organism.getConservationStatus()) {
            item.setOrganism(null);
        }
        // Clear bidirectional one-to-many parent relationship with Distribution
        for (Distribution item : organism.getDistribution()) {
            item.setOrganism(null);
        }
        // Clear bidirectional many-to-many parent relationship with Document
        for (Document item : organism.getDocs()) {
            item.getOrganisms().remove(organism);
        }
        // Clear bidirectional one-to-many parent relationship with OrganismDocument
        for (OrganismDocument item : organism.getDocuments()) {
            item.setOrganism(null);
        }
        // Clear bidirectional one-to-many parent relationship with Germplasm
        for (Germplasm item : organism.getGermplasm()) {
            item.setOrganism(null);
        }
        // Clear bidirectional one-to-many parent relationship with OrganismImage
        for (OrganismImage item : organism.getImages()) {
            item.setOrganism(null);
        }
        // Clear bidirectional one-to-many parent relationship with OrganismSpecimen
        for (OrganismSpecimen item : organism.getSpecimens()) {
            item.setOrganism(null);
        }
        // Clear bidirectional one-to-many parent relationship with Taxonomy
        for (Taxonomy item : organism.getTaxonomy()) {
            item.setOrganism(null);
        }
        // Clear bidirectional one-to-many parent relationship with OrganismVideo
        for (OrganismVideo item : organism.getVideos()) {
            item.setOrganism(null);
        }
        getOrganismRepository().delete(organism);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param entities
     * @return List
     */
    @Override
    @Transactional
    public List<Organism> save(Iterable<Organism> entities) {
        return getOrganismRepository().save(entities);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param ids
     */
    @Override
    @Transactional
    public void delete(Iterable<Long> ids) {
        List<Organism> toDelete = getOrganismRepository().findAll(ids);
        getOrganismRepository().deleteInBatch(toDelete);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param entity
     * @return Organism
     */
    @Override
    @Transactional
    public Organism save(Organism entity) {

        entity.getTaxonomy().forEach(it -> it.setOrganism(entity));
        entity.getDistribution().forEach(it -> it.setOrganism(entity));
        entity.getSpecimens().forEach(it -> it.setOrganism(entity));
        entity.getDocuments().forEach(it -> it.setOrganism(entity));
        entity.getVideos().forEach(it -> it.setOrganism(entity));
        entity.getImages().forEach(it -> it.setOrganism(entity));
        entity.getConservationStatus().forEach(it -> it.setOrganism(entity));
        entity.getGermplasm().forEach(it -> it.setOrganism(entity));

        return getOrganismRepository().save(entity);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param id
     * @return Organism
     */
    @Override
    public Organism findOne(Long id) {
        return getOrganismRepository().findOne(id);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param id
     * @return Organism
     */
    @Override
    public Organism findOneForUpdate(Long id) {
        return getOrganismRepository().findOneDetached(id);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param ids
     * @return List
     */
    @Override
    public List<Organism> findAll(Iterable<Long> ids) {
        return getOrganismRepository().findAll(ids);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return List
     */
    @Override
    public List<Organism> findAll() {
        return getOrganismRepository().findAll();
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return Long
     */
    @Override
    public long count() {
        return getOrganismRepository().count();
    }

    @Override
    public Page<Organism> search(Predicate predicate, Pageable pageable) {
        //return getOrganismAdvanceRepository().findAll(predicate, pageable);
        return getOrganismRepository().findAll(predicate, pageable);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param globalSearch
     * @param pageable
     * @return Page
     */
    @Override
    public Page<Organism> findAll(GlobalSearch globalSearch, Pageable pageable) {
        return getOrganismRepository().findAll(globalSearch, pageable, null);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param globalSearch
     * @param pageable
     * @return Page
     */
    @Override
    public Page<Organism> findAll(GlobalSearch globalSearch, Pageable pageable, String creator) {
        return getOrganismRepository().findAll(globalSearch, pageable, creator);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param ids
     * @param globalSearch
     * @param pageable
     * @return Page
     */
    @Override
    public Page<Organism> findAllByIdsIn(List<Long> ids, GlobalSearch globalSearch, Pageable pageable) {

        return getOrganismRepository().findAllByIdsIn(ids, globalSearch, pageable);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param name
     * @param pageable
     * @return Page
     */
    @Override
    public Page<String> findNameByNameLike(String name, Pageable pageable) {
        Page<Organism> organisms = getOrganismRepository().findAllByNameLike(name, pageable);
        Page<String> ret = organisms.map(it -> it.getName());
        return ret;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param name
     * @return Long
     */
    @Override
    public long countByNameLike(String name) {
        return getOrganismRepository().countByNameLike(name);
    }

    @Override
    public List<NamingPair3> findAllByInitial(String initial) {
        return getOrganismRepository().findAllByInitial(initial);
    }

    @Override
    public Object queryById(Long s) {
        return organismRepository.queryById(s);
    }


//    @Override
//    public Page<Organism> findByPageAndSize( String creator, String name, Pageable pageable) {
//        Specification<Organism> specification=new Specification<Organism>() {
//            @Override
//            public javax.persistence.criteria.Predicate toPredicate(Root<Organism> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//
//                Path<String> _name = root.get("name");//关键字
//                Path<String> _creator = root.get("creator");//城建人
//                javax.persistence.criteria.Predicate _key = criteriaBuilder.like(_name, "%" + name + "%");
//                javax.persistence.criteria.Predicate _creator_key = criteriaBuilder.like(_creator, "%" + creator + "%");
//                 //创建人不能为空
//                if (StringUtils.isNotBlank(creator)&&!creator.equals("null")) {
//                    return criteriaBuilder.and(_key, _creator_key);
//                }
//                return criteriaBuilder.and(_key);
//            }
//        };
//        return getOrganismRepository().findAll(specification,pageable);
//    }

    @Override
    public List getPageList1(List<Long> ids,Pageable pageable){
        List ob = new ArrayList <>(  );
        List<O> os = new ArrayList <>(  );
        ids = ids.size()>0?ids:null;
        List<Object> list = organismRepository.findByIds(ids,pageable );
        for (Object o:list){
            O o1 = new O();
            Object[] objects = (Object[]) o;
            o1.setId( Long.parseLong( ""+objects[0] ) );
            o1.setName( ""+objects[1] );
            o1.setName_en( ""+objects[2] );
            os.add( o1 );
        }
        ob.add( ids!=null?ids.size():0 );
        ob.add( os );
        return ob;
    }

    @Override
    public List findByPageAndSize(String latinName,
                                            String kingdom,
                                            String family,
                                            String genus,
                                            String country,
                                            String province,
                                            String city,
                                            String name,
                                            Pageable pageable1) {
        //获取分类id集合
        List<Long> tIds = new ArrayList <>(  );
        String sign = null;
        //当参数有一个不为空时进入
        if(!(kingdom==null||"".equals( kingdom ))||!(family==null||"".equals( family ))||!(genus==null||"".equals( genus ))){
            tIds = taxonomyRepository.getIdsByKingdomAndFamilyAndAndGenus(kingdom,family,genus);
            sign = "0";
        }
        tIds = tIds.size()>0?tIds:null;
        //获取地区id集合
        List<Long> dIds = new ArrayList <>(  );
        //当参数有一个不为空时进入
        if(!(country==null||"".equals( country ))||!(province==null||"".equals( province ))||!(city==null||"".equals( city ))){
            dIds = distributionRepository.getIdsByCountryAndProvinceAndCityAndIds(country,province,city,null,sign,tIds);
            sign = "1";
        }
        dIds = dIds.size()>0?dIds:null;
        List list = new ArrayList(  );
        List<NewClass> organisms = new ArrayList <>(  );
        for(Object o:organismRepository.queryAllByKeyAndIds(name,latinName,sign,"1".equals( sign )?dIds:tIds,pageable1)){
            Object[] objects = (Object[]) o;
            NewClass newOrganism = new NewClass();
            newOrganism.setId( ObjectNull.takeOutNull(objects[0]));
            newOrganism.setNumber( ObjectNull.takeOutNull(objects[0]));
            newOrganism.setName( ObjectNull.takeOutNull(objects[1]));
            newOrganism.setLatin_name( ObjectNull.takeOutNull(objects[2]) );
            newOrganism.setInitial( ObjectNull.takeOutNull(objects[3]));
            newOrganism.setCreator( ObjectNull.takeOutNull(objects[4]));
            newOrganism.setNamed_info( ObjectNull.takeOutNull(objects[5]));
            List<String> strings = organismImageRepository.getUrl( Long.parseLong( ""+objects[0] ) );
            newOrganism.setUrl( strings.size()>0?strings.get( 0 ):null );
            organisms.add( newOrganism );
        }
        list.add( organismRepository.queryCountByKey( name,latinName,sign,"1".equals( sign )?dIds:tIds ) );
        list.add( organisms );
        return list;
    }

    @Override
    public List getCountByPhylumn(String phylumn) {
        List<Long> areaIds = distributionRepository.queryIdByProvince("贵州");
        String [] phylumns =phylumn.split("、");
        List<Long> num = new ArrayList<>();
        num.add(organismRepository.getCountByPhulumn(phylumns[0],areaIds.size()>0?areaIds:null));
        num.add(organismRepository.getCountByPhulumn(phylumns[1],areaIds.size()>0?areaIds:null));
        num.add(organismRepository.getCountByPhulumn(phylumns[2],areaIds.size()>0?areaIds:null));
        return num;
    }

    @Override
    public List getCountByUseValue(String useValue) {
        List<Long> areaIds = distributionRepository.queryIdByProvince("贵州");
        String [] useValues =useValue.split("、");
        List<Long> num = new ArrayList<>();
        num.add(organismRepository.getCountByUseValue(useValues[0],areaIds.size()>0?areaIds:null));
        num.add(organismRepository.getCountByUseValue(useValues[1],areaIds.size()>0?areaIds:null));
        num.add(organismRepository.getCountByUseValue(useValues[2],areaIds.size()>0?areaIds:null));
        return num;
    }

    @Override
    public List getOrganismAndTaxonomyByCityAndCountry(String city, String county, String kingdom,String phylumn,String tClass,String tOrder,String family, String genus,Pageable pageable) {

        List organism = new ArrayList();
        List<Long> ids = distributionRepository.queryCounty("贵州",city,county);
        ids = ids.size()>0?ids:null;
        List<Long> ids1 = organismRepository.getOrganismIdByFamilyAndGenus(kingdom,phylumn,tClass,tOrder,family,genus);
        ids1 = ids1.size()>0?ids1:null;
        List<Object> obj =organismRepository.getOrganismInfoByFamilyAndGenus(ids,ids1,pageable);
        //获取总的记录数
        Long num = organismRepository.getCountByFamilyAndGenus(ids,ids1);
        List<NewOrganism> organisms = new ArrayList<>();
        for (Object object:obj){
            NewOrganism newOrganism = new NewOrganism();
            Object[] objects = (Object[]) object;
            newOrganism.setId( ""+objects[0] );
            newOrganism.setName( ""+objects[1] );
            newOrganism.setLatin_name( ""+objects[2] );
            organisms.add( newOrganism );
        }

        organism.add(num!=null?num:0);
        organism.add(organisms);
        return  organism;
    }

    @Override
    public List getTree(String city, String county, String kingdom, String phylumn, String tClass, String tOrder, String family) {
        List<Long> organismIds = distributionRepository.getIds( county,"贵州",city);
        String sign = organismIds.size()>0?"end":null;
        if(family!=null&&!("".equals( family ))){
            return getDataTree( taxonomyRepository.getByFamilys( kingdom,phylumn,tClass,tOrder,family,sign,organismIds),"end" );
        }
        if(tOrder!=null&&!("".equals( tOrder ))){
            return getDataTree( taxonomyRepository.getByTOrder( kingdom,phylumn,tClass,tOrder,sign,organismIds),null );
        }
        if(tClass!=null&&!("".equals( tClass ))){
            return getDataTree( taxonomyRepository.getByTClass( kingdom,phylumn,tClass,sign,organismIds),null );
        }
        if(phylumn!=null&&!("".equals( phylumn ))){
            return getDataTree( taxonomyRepository.getByPhylumn( kingdom,phylumn,sign,organismIds),null );
        }
        if(kingdom!=null&&!("".equals( kingdom ))){
            return getDataTree( taxonomyRepository.getByKingdom( kingdom,sign,organismIds),null );
        }
        if(county!=null&&!("".equals( county ))){
            return getDataTree( taxonomyRepository.getByCounty( sign,organismIds),null );
        }
        if(city!=null&&!("".equals( city ))){
            return getDataTree( distributionRepository.getByCity("贵州",city),"start");
        }
        return getDataTree( distributionRepository.getByProvince("贵州"),"start");

    }

    /**
     * 获取数据树
     * @param objects
     * @param sign
     * @return
     */
    List getDataTree(List objects,String sign){
        List<Tree> trees = new ArrayList <>(  );
        if(objects.size()>0){
            if("end".equals( sign )){
                for (Object o:objects){
                    Tree tree = new Tree();
                    Object[] object = (Object[]) o;
                    if(object[0]==null||"".equals( object[0]+"" )){
                        continue;
                    }
                    tree.setName( (object[0]+" "+object[1]).trim() );
                    tree.setChildren( null );
                    trees.add( tree );
                }
                return trees;
            }else {
                for (Object o:objects){
                    Tree tree = new Tree();
                    if("start".equals( sign )){
                        if(o==null||"".equals( o+"" )){
                            continue;
                        }
                        tree.setName( o+"" );
                    }else {
                        Object[] object = (Object[]) o;
                        if(object[0]==null||"".equals( object[0]+"" )){
                            continue;
                        }
                        tree.setName( (object[0]+" "+object[1]).trim() );
                    }
                    tree.setChildren( new ArrayList <>(  ) );
                    trees.add( tree );
                }
                return trees;
            }
        }
        return null;
    }

    class NewOrganism{

        private String id;

        private String name;

        private String latin_name;

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getLatin_name() {
            return latin_name;
        }

        public void setLatin_name(String latin_name) {
            this.latin_name = latin_name;
        }


    }
    /**
     * 获取市下面的物种
     * @param city
     * @param pageable
     * @return
     */
    @Override
    public List getPageList(String city,Pageable pageable) {
        List ob = new ArrayList <>(  );
        List<O> os = new ArrayList <>(  );
        List<Long> ids = new ArrayList <>(  );
        for(Object o:distributionRepository.findIdByCity(city)){
            ids.add( Long.parseLong( ""+o ) );
        }
        List<Object> list = organismRepository.findByIds(ids,pageable );
        for (Object o:list){
            O o1 = new O();
            Object[] objects = (Object[]) o;
            o1.setId( Long.parseLong( ""+objects[0] ) );
            o1.setName( ""+objects[1] );
            o1.setName_en( ""+objects[2] );
            os.add( o1 );
        }
        ob.add( ids.size() );
        ob.add( os );
        return ob;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return Class
     */
    @Override
    public Class<Organism> getEntityType() {
        return Organism.class;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return Class
     */
    @Override
    public Class<Long> getIdType() {
        return Long.class;
    }
}
